package yourobot;


import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;

import org.jbox2d.common.Vec2;
import org.jbox2d.dynamics.Body;
import org.jbox2d.dynamics.World;

import yourobot.robots.Player;
import fr.umlv.zen.ApplicationCode;
import fr.umlv.zen.ApplicationContext;
import fr.umlv.zen.ApplicationRenderCode;
import fr.umlv.zen.KeyboardEvent;

/**
 * 
 * @author mehdimasrour
 *
 */
public class Game implements ApplicationCode {
	
	private final static int DEFAULTPLAYERS=1;
	private final static int MAXPLAYERS=2;
	private final static int DEFAULTLEVEL=1;
	private final static int MAXLEVELS=10;
	
	private int level;
	private final int levels;
	private final int nbPlayers;
	private final World worldmap;
	private Level myLevel;
	
	/**
	 * Starts a new game
	 * @param numberPlayers
	 * @param numberLevels
	 */
	public Game(int numberPlayers, int numberLevels){
		if ( numberPlayers > MAXPLAYERS ) throw new IllegalArgumentException("Max number of players = "+MAXPLAYERS);
		if ( numberLevels > MAXLEVELS ) throw new IllegalArgumentException("Max number of levels = "+MAXLEVELS);
		
		levels = numberLevels;
		nbPlayers = numberPlayers;
		level=1;
		worldmap = new World(new Vec2(0, 0), true);
		MyContactListener contactlistener = new MyContactListener();
		worldmap.setContactListener(contactlistener);
		
		myLevel = new Level(worldmap,nbPlayers);
	}
	
	public Game(){
		this(DEFAULTPLAYERS,DEFAULTLEVEL);
	}
	
	/**
	 * Starts a new level
	 */
	public void newLevel(){
		Body b = worldmap.getBodyList();
		while (b != null){
			Body tmp = b.getNext();
			worldmap.destroyBody(b);
			b = tmp;
		}
		myLevel.getPlayers().clear();
		for ( int i=1; i<(nbPlayers+1); i++ ){
			myLevel.getPlayers().add(new Player(i,worldmap,myLevel.getStart()));
		}
		myLevel = new Level(worldmap,nbPlayers);
	}
	
	/**
	 * 
	 * @return the current level
	 */
	public int getLevel(){
		return level;
	}
	
	/**
	 * 
	 * @return the number of levels
	 */
	public int getLastLevel(){
		return levels;
	}

	@Override
	public void run(ApplicationContext context) {
		KeyboardEvent k;
		boolean finished = false;
		while (!finished){
			worldmap.step(1.0f/60.0f, 6, 2);
			context.render(myLevel);
			if ( myLevel.gameOver() ) {
				context.render(new ApplicationRenderCode() {
					
					@Override
					public void render(Graphics2D graphics) {
						BufferedImage im = null;
						try {
							im = ImageIO.read(new File("gameover.jpg"));
						} catch (IOException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						}
						graphics.drawImage(im, 0, 0, null);
					}
				});
				System.out.println("GAME OVER...");
				finished=true;
				break;
			}
			k = context.pollKeyboard();
			for ( Player p : myLevel.getPlayers() ){
				if( p.hasFinishedLevel(myLevel) ){
					System.out.println("Level "+level+"/"+levels+" finished by Player "+p.getId());
					if( level == levels ){
						System.out.println("GAME FINISHED!!!");
						context.render(new ApplicationRenderCode() {
							
							@Override
							public void render(Graphics2D graphics) {
								BufferedImage im = null;
								try {
									im = ImageIO.read(new File("finish.jpg"));
								} catch (IOException e) {
									// TODO Auto-generated catch block
									e.printStackTrace();
								}
								graphics.drawImage(im, 0, 0, null);
							}
						});
						finished=true;
						break;
					}
					else{
						level++;
						newLevel();
						break;
					}
				}
				if ( k != null ){
					p.addKey(k);
				}

				try {
					Thread.sleep(4);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}
		

	}

}
